//
//  GroupTableView.m
//  etionUI
//
//  Created by wangjian on 8/9/13.
//
//

#import "GroupTableView.h"
#import "GroupTableViewGroup.h"

#import "UIStyleSkinManager.h"

#import "UIStyleSkinManagerInternal.h"

@interface CScrollView : UIScrollView

@end

@implementation CScrollView

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    if (!self.dragging)
    {
        [[self nextResponder] touchesBegan:touches withEvent:event];
    }
    else
    {
        [super touchesBegan:touches withEvent:event];
    }
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    if (!self.dragging)
    {
        [self.nextResponder touchesMoved:touches withEvent:event];
    }
    else
    {
        [super touchesMoved:touches withEvent:event];
    }
}

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
    if (self.dragging)
    {
        [[self nextResponder] touchesCancelled:touches withEvent:event];
    }
    else
    {
        [super touchesCancelled:touches withEvent:event];
    }
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    if (!self.dragging)
    {
        [[self nextResponder] touchesEnded:touches withEvent:event];
    }
    else
    {
        [super touchesEnded:touches withEvent:event];
    }
}

@end

@implementation CGroupBackgroundInfo

+ (CGroupBackgroundInfo *)infoWithImage:(UIImage *)image borderEdgeInsets:(UIEdgeInsets)borderEdgeInsets cornerRadius:(CGFloat)cornerRadius
{
    CGroupBackgroundInfo *info = [[[CGroupBackgroundInfo alloc] init] autorelease];
    
    info.image = image;
    info.borderEdgeInsets = borderEdgeInsets;
    info.cornerRadius = cornerRadius;
    
    return info;
}

- (void)dealloc
{
    [_image release];
    superdealloc_mm;
}

@end

@interface CGroupTableView()

@property (nonatomic, retain) NSMutableArray *groups;
@property (nonatomic, retain) NSIndexPath *curSelectedIndexPath;
@property (nonatomic, retain) NSIndexPath *preSelectedIndexPath;

@property (nonatomic, retain) UIImage *groupBgImage;
@property (nonatomic, assign) UIEdgeInsets groupBgEdgeInsets;
@property (nonatomic, assign) CGFloat cornerRadius;

@property (nonatomic, retain) NSMutableDictionary *dicHeaderView;
@property (nonatomic, retain) NSMutableDictionary *dicFooterView;

@end

@implementation CGroupTableView

@synthesize delegate = _delegate;
@synthesize separatorSize = _separatorSize;
@synthesize separatorColor = _separatorColor;

@synthesize groupBgImage = _groupBgImage;
@synthesize groupBgEdgeInsets = _groupBgEdgeInsets;
@synthesize cornerRadius = _cornerRadius;

@synthesize scrollView = _scrollView;
@synthesize groups = _groups;
@synthesize curSelectedIndexPath = _curSelectedIndexPath;
@synthesize preSelectedIndexPath = _preSelectedIndexPath;

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        self.backgroundColor = [UIColor colorWithHex:0xe6e6e6];
        
        self.groupBackgroundColor = [UIColor clearColor];
        self.separatorSize = .5;
        self.separatorColor = [UIColor colorWithHex:0xd2d8df];
        self.borderEdgeInsets = UIEdgeInsetsMake(10, 10, 10, 10);
        self.groupSpacing = 10;
        
        self.groupBgImage = [[UIImage imageNamed:@"gtv_group_bg"] resizeableCenterImage];
        self.groupBgEdgeInsets = UIEdgeInsetsMake(1, 1, 1.5, 1);
        self.cornerRadius = 2.5;
        
        XUIGroupTableViewStyleSkin* uiss = [CUIStyleSkinManager getGroupTableViewStyleSkin];
        if(uiss != nil)
        {
            if(uiss.separatorColor != nil)
            {
                self.separatorColor = uiss.separatorColor;
            }
            
            if(uiss.backgroundColor != nil)
            {
                self.backgroundColor = uiss.backgroundColor;
            }
        }
    }
    return self;
}

- (void)setFrame:(CGRect)frame
{
    [super setFrame:frame];
    self.scrollView.frame = self.bounds;
}

- (NSMutableArray *)groups
{
    if (_groups == nil)
    {
        _groups = [[NSMutableArray alloc] init];
    }
    return _groups;
}

- (NSMutableDictionary *)dicHeaderView
{
    if (_dicHeaderView == nil)
    {
        _dicHeaderView = [[NSMutableDictionary alloc] init];
    }
    return _dicHeaderView;
}

- (NSMutableDictionary *)dicFooterView
{
    if (_dicFooterView == nil)
    {
        _dicFooterView = [[NSMutableDictionary alloc] init];
    }
    return _dicFooterView;
}

- (UIScrollView *)scrollView
{
    if (_scrollView == nil)
    {
        _scrollView = [[CScrollView alloc] initWithFrame:self.bounds];
        _scrollView.backgroundColor = [UIColor clearColor];
//        _scrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
        [self addSubview:_scrollView];
    }
    return _scrollView;
}

- (void)dealloc
{
    [_separatorColor release_mm];
    [_groupBgImage release_mm];
    
    [_scrollView release_mm];
    [_groups release_mm];
    [_curSelectedIndexPath release_mm];
    [_preSelectedIndexPath release_mm];
    
    [_dicHeaderView release_mm];
    [_dicFooterView release_mm];
    superdealloc_mm;
}

#pragma mark interface

- (CGFloat)cellContentWidth
{
    return self.width-2*self.borderEdgeInsets.left-self.groupBgEdgeInsets.left-self.groupBgEdgeInsets.right;
}

- (CGroupTableViewCell *)cellAtIndexPath:(NSIndexPath *)indexPath
{
    CGroupTableViewGroup *group = [self.groups objectAtIndex:indexPath.section];
    return [group.cells objectAtIndex:indexPath.row];
}

- (CGroupTableViewCell *)cellWithTag:(NSString*)szTag
{
    for(CGroupTableViewGroup *group in self.groups)
    {
        for(CGroupTableViewCell * c in group.cells)
        {
            if([c.szTag isEqualToString:szTag])
            {
                return c;
            }
        }
    }
    return nil;
}

- (NSIndexPath *)indexPathOfCell:(CGroupTableViewCell *)cell
{
    NSIndexPath *indexPath = nil;
    for (NSInteger groupId=0; groupId<self.groups.count; groupId++)
    {
        CGroupTableViewGroup *group = [self.groups objectAtIndex:groupId];
        NSUInteger rowId = [group.cells indexOfObject:cell];
        if (rowId != NSNotFound)
        {
            indexPath = [NSIndexPath indexPathForRow:rowId inSection:groupId];
            break;
        }
    }
    return indexPath;
}

- (CGRect)frameOfGroup:(NSUInteger)groupId
{
    if (self.groups.count == 0 || groupId > self.groups.count-1)
    {
        return CGRectZero;
    }
    CGroupTableViewGroup *group = [self.groups objectAtIndex:groupId];
    return group.frame;
}

- (CGRect)frameOfCellAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath == nil)
    {
        return CGRectZero;
    }
    CGroupTableViewGroup *group = [self.groups objectAtIndex:indexPath.section];
    CGroupTableViewCell *cell = [group.cells objectAtIndex:indexPath.row];
    CGRect cellFrame = cell.frame;
    cellFrame.origin.y += group.frame.origin.y;
    return cellFrame;
}

- (void)setGroupBackgroundImageWithImage:(UIImage *)image borderEdgeInsets:(UIEdgeInsets)borderEdgeInsets cornerRadius:(CGFloat)cornerRadius
{
    self.groupBgImage = image;
    self.groupBgEdgeInsets = borderEdgeInsets;
    self.cornerRadius = cornerRadius;
}

- (void)selectRowAtIndexPath:(NSIndexPath *)indexPath animated:(BOOL)animated
{
    
}

- (void)deselectRowAtIndexPath:(NSIndexPath *)indexPath animated:(BOOL)animated
{
    
}

- (void)scrollToIndexPath:(NSIndexPath *)indexPath animated:(BOOL)animated
{
    if (indexPath == nil)
    {
        return;
    }

    CGRect cellFrame = [self frameOfCellAtIndexPath:indexPath];
    cellFrame.size.height += self.borderEdgeInsets.top;
    [self.scrollView scrollRectToVisible:cellFrame animated:animated];
}

#pragma mark edit

- (void)resizeRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation complete:(void (^)(BOOL finished))complete
{
    NSDictionary *dicIndexPaths = [self reorderInsertIndexPaths:indexPaths];
    
    for (NSInteger groupId = 0; groupId < self.groups.count; groupId++)
    {
        CGroupTableViewGroup *group = [self.groups objectAtIndex:groupId];
        NSArray *arRows = [dicIndexPaths objectForKey:[NSNumber numberWithInteger:groupId]];
        if (arRows != nil)
        {
            [UIView animateWithDuration:GROUP_TABLE_VIEW_ANIMATION_DURATION animations:^
            {
                [arRows enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop)
                {
                    CGroupTableViewCell *cell = [group.cells objectAtIndex:[obj integerValue]];
                    cell.height = [self.delegate groupTableView:self heightForRowAtIndexPath:[NSIndexPath indexPathForRow:[obj integerValue] inSection:groupId]];
                }];
            }];
            [group resizeCells];
        }
    }
    
    __block CGFloat curContentH = self.groupSpacing;
    [UIView animateWithDuration:GROUP_TABLE_VIEW_ANIMATION_DURATION animations:^{
        for (NSInteger groupId = 0; groupId < self.groups.count; groupId++)
        {
            UIView *headerView = [self.dicHeaderView objectForKey:[NSNumber numberWithInteger:groupId]];
            if (headerView != nil)
            {
                headerView.top = curContentH;
                curContentH += headerView.height;
            }
            
            CGroupTableViewGroup *group = [self.groups objectAtIndex:groupId];
            group.frame = CGRectMake(group.left, curContentH, group.width, group.height);
            curContentH += group.height;
            
            UIView *footerView = [self.dicFooterView objectForKey:[NSNumber numberWithInteger:groupId]];
            if (footerView != nil)
            {
                footerView.top = curContentH;
                curContentH += footerView.height;
            }
            curContentH += groupId==self.groups.count-1 ? self.borderEdgeInsets.bottom : self.groupSpacing;
        }
    } completion:^(BOOL finished) {
        self.scrollView.contentSize = CGSizeMake(self.width, curContentH);
        complete(finished);
    }];
}

- (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation complete:(void (^)(BOOL finished))complete
{
    NSDictionary *dicIndexPaths = [self reorderInsertIndexPaths:indexPaths];
    
    for (NSInteger groupId = 0; groupId < self.groups.count; groupId++)
    {
        CGroupTableViewGroup *group = [self.groups objectAtIndex:groupId];
        NSArray *arRows = [dicIndexPaths objectForKey:[NSNumber numberWithInteger:groupId]];
        if (arRows != nil)
        {
            NSMutableArray *arReloadCells = [NSMutableArray array];
            [arRows enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
                [arReloadCells addObject:[self cellForIndexPath:[NSIndexPath indexPathForRow:[obj integerValue] inSection:groupId]]];
            }];
            [group reloadCells:arReloadCells atRows:arRows withRowAnimation:animation];
        }
    }
    
    __block CGFloat curContentH = self.groupSpacing;
    void(^fun1)()=^
    {
        for (NSInteger groupId = 0; groupId < self.groups.count; groupId++)
        {
            UIView *headerView = [self.dicHeaderView objectForKey:[NSNumber numberWithInteger:groupId]];
            if (headerView != nil)
            {
                headerView.top = curContentH;
                curContentH += headerView.height;
            }
            
            CGroupTableViewGroup *group = [self.groups objectAtIndex:groupId];
            group.frame = CGRectMake(group.left, curContentH, group.width, group.height);
            curContentH += group.height;
            
            UIView *footerView = [self.dicFooterView objectForKey:[NSNumber numberWithInteger:groupId]];
            if (footerView != nil)
            {
                footerView.top = curContentH;
                curContentH += footerView.height;
            }
            curContentH += groupId==self.groups.count-1 ? self.borderEdgeInsets.bottom : self.groupSpacing;
        }
    };
    void(^fun2)(BOOL finished)=^(BOOL finished)
    {
        self.scrollView.contentSize = CGSizeMake(self.width, curContentH);
        complete(finished);
    };
    if(animation==UITableViewRowAnimationNone)
    {
        fun1();
        fun2(YES);
    }
    else
    {
        [UIView animateWithDuration:GROUP_TABLE_VIEW_ANIMATION_DURATION animations:^
        {
            fun1();
        } completion:^(BOOL finished)
        {
            fun2(finished);
        }];
    }
}

- (NSDictionary *)reorderDelIndexPaths:(NSArray *)indexPaths
{
    NSMutableDictionary *dicIndexPaths = [NSMutableDictionary dictionary];
    for (NSIndexPath *indexPath in indexPaths)
    {
        NSMutableDictionary *dicSection = [dicIndexPaths objectForKey:[NSNumber numberWithInteger:indexPath.section]];
        if (dicSection == nil)
        {
            dicSection = [NSMutableDictionary dictionary];
            [dicIndexPaths setObject:dicSection forKey:[NSNumber numberWithInteger:indexPath.section]];
        }
        [dicSection setObject:[NSNumber numberWithInteger:indexPath.row] forKey:[NSNumber numberWithInteger:indexPath.row]];
    }
    return dicIndexPaths;
}

- (NSDictionary *)reorderInsertIndexPaths:(NSArray *)indexPaths
{
    NSMutableDictionary *dicIndexPaths = [NSMutableDictionary dictionary];
    for (NSIndexPath *indexPath in indexPaths)
    {
        NSMutableArray *arRows = [dicIndexPaths objectForKey:[NSNumber numberWithInteger:indexPath.section]];
        if (arRows == nil)
        {
            arRows = [NSMutableArray array];
            [dicIndexPaths setObject:arRows forKey:[NSNumber numberWithInteger:indexPath.section]];
        }
        [arRows addObject:[NSNumber numberWithInteger:indexPath.row]];
    }
    return dicIndexPaths;
}

- (void)insertRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation complete:(void (^)(BOOL finished))complete
{
    NSDictionary *dicIndexPaths = [self reorderInsertIndexPaths:indexPaths];
    
    for (NSInteger groupId = 0; groupId < self.groups.count; groupId++)
    {
        CGroupTableViewGroup *group = [self.groups objectAtIndex:groupId];
        NSArray *arRows = [dicIndexPaths objectForKey:[NSNumber numberWithInteger:groupId]];
        if (arRows != nil)
        {
            NSMutableArray *arInsertCells = [NSMutableArray array];
            [arRows enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop)
            {
                [arInsertCells addObject:[self cellForIndexPath:[NSIndexPath indexPathForRow:[obj integerValue] inSection:groupId]]];
            }];
            [group prepareInsertCells:arInsertCells atRows:arRows withRowAnimation:animation];
        }
    }
    
    __block CGFloat curContentH = self.groupSpacing;
    
    void(^f1)()=^
    {
        for (NSInteger groupId = 0; groupId < self.groups.count; groupId++)
        {
            UIView *headerView = [self.dicHeaderView objectForKey:[NSNumber numberWithInteger:groupId]];
            if (headerView != nil)
            {
                headerView.top = curContentH;
                curContentH += headerView.height;
            }
            
            CGroupTableViewGroup *group = [self.groups objectAtIndex:groupId];
            if ([dicIndexPaths objectForKey:[NSNumber numberWithInteger:groupId]] != nil)
            {
                [group startInsertAnimation:animation];
            }
            group.frame = CGRectMake(group.left, curContentH, group.width, group.height);
            curContentH += group.height;
            
            UIView *footerView = [self.dicFooterView objectForKey:[NSNumber numberWithInteger:groupId]];
            if (footerView != nil)
            {
                footerView.top = curContentH;
                curContentH += footerView.height;
            }
            curContentH += groupId==self.groups.count-1 ? self.borderEdgeInsets.bottom : self.groupSpacing;
        }
    };
    void(^f2)()=^
    {
        self.scrollView.contentSize = CGSizeMake(self.width, curContentH);
    };
    
    if(animation != UITableViewRowAnimationNone)
    {
        [UIView animateWithDuration:GROUP_TABLE_VIEW_ANIMATION_DURATION animations:^
        {
            f1();
        } completion:^(BOOL finished)
        {
            f2();
            complete(finished);
        }];
    }
    else
    {
        f1();
        f2();
        complete(YES);
    }
}

- (void)deleteRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation complete:(void (^)(BOOL finished))complete
{
    NSDictionary *dicIndexPaths = [self reorderDelIndexPaths:indexPaths];
    
    __block CGFloat curContentH = self.borderEdgeInsets.top;
    
    void(^f1)()=^
    {
        for (NSInteger groupId = 0; groupId < self.groups.count; groupId++)
        {
            UIView *headerView = [self.dicHeaderView objectForKey:[NSNumber numberWithInteger:groupId]];
            if (headerView != nil)
            {
                headerView.top = curContentH;
                curContentH += headerView.height;
            }
            
            CGroupTableViewGroup *group = [self.groups objectAtIndex:groupId];
            NSDictionary *dicGroupRows = [dicIndexPaths objectForKey:[NSNumber numberWithInteger:groupId]];
            if (dicGroupRows != nil)
            {
                [group deleteRows:dicGroupRows withRowAnimation:animation];
            }
            group.frame = CGRectMake(group.left, curContentH, group.width, group.height);
            curContentH += group.height;
            
            UIView *footerView = [self.dicFooterView objectForKey:[NSNumber numberWithInteger:groupId]];
            if (footerView != nil)
            {
                footerView.top = curContentH;
                curContentH += footerView.height;
            }
            curContentH += groupId==self.groups.count-1 ? self.borderEdgeInsets.bottom : self.groupSpacing;
        }
    };
    void(^f2)()=^
    {
        self.scrollView.contentSize = CGSizeMake(self.width, curContentH);
        [dicIndexPaths enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop)
        {
            CGroupTableViewGroup *group = [self.groups objectAtIndex:[key integerValue]];
            [group deleteRowsAnimationComplete:obj];
        }];
    };
    
    if(animation != UITableViewRowAnimationNone)
    {
        [UIView animateWithDuration:.3 animations:^
        {
            f1();
        } completion:^(BOOL finished)
        {
            f2();
            complete(finished);
        }];
    }
    else
    {
        f1();
        f2();
        complete(YES);
    }
}

#pragma mark inner method

- (NSUInteger)numberOfGroup
{
    if ([self.delegate respondsToSelector:@selector(numberOfGroupInGroupTableView:)])
    {
        return [self.delegate numberOfGroupInGroupTableView:self];
    }
    return 1;
}

- (CGFloat)heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if ([self.delegate respondsToSelector:@selector(groupTableView:heightForRowAtIndexPath:)])
    {
        return [self.delegate groupTableView:self heightForRowAtIndexPath:indexPath];
    }
    return 44;
}

- (CGroupTableViewCell *)cellForIndexPath:(NSIndexPath *)indexPath
{
    CGroupTableViewCell *cell = [self.delegate groupTableView:self cellForRowAtIndexPath:indexPath];
    CGFloat rowH = [self heightForRowAtIndexPath:indexPath];
    cell.frame = CGRectMake(0, 0, self.width, rowH);
    return cell;
}

- (void)reloadData
{
    [self.dicHeaderView enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop)
    {
        [obj removeFromSuperview];
    }];
    [self.dicHeaderView removeAllObjects];
    
    [self.dicFooterView enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop)
    {
        [obj removeFromSuperview];
    }];
    [self.dicFooterView removeAllObjects];
    
    if (self.groups.count > 0)
    {
        [self.groups enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
            CGroupTableViewGroup *groupView = obj;
            [groupView.cells enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
                [obj removeFromSuperview];
            }];
            [groupView removeFromSuperview];
        }];
        [self.groups removeAllObjects];
    }
    
    CGFloat curContentH = self.borderEdgeInsets.top;
    NSUInteger groupNumber = [self numberOfGroup];
    for (NSInteger group=0; group<groupNumber; group++)
    {
        //add header view
        if ([self.delegate respondsToSelector:@selector(groupTableView:viewForHeaderInGroup:)])
        {
            UIView *headerView = [self.delegate groupTableView:self viewForHeaderInGroup:group];
            if (headerView != nil)
            {
                headerView.frame = CGRectMake(self.borderEdgeInsets.left, curContentH, self.width-2*self.borderEdgeInsets.left, headerView.height);
                curContentH += headerView.height;
                [self.scrollView addSubview:headerView];
                [self.dicHeaderView setObject:headerView forKey:[NSNumber numberWithInteger:group]];
            }
        }
        
        NSUInteger rowNumber = [self.delegate groupTableView:self numberOfRowsInGroup:group];
        NSMutableArray *cells = [NSMutableArray array];
        for (NSInteger row=0; row<rowNumber; row++)
        {
            [cells addObject:[self cellForIndexPath:[NSIndexPath indexPathForRow:row inSection:group]]];
        }
        CGroupTableViewGroup *groupView = [[CGroupTableViewGroup alloc] initWithFrame:CGRectMake(self.borderEdgeInsets.left, curContentH, self.width-2*self.borderEdgeInsets.left, 0)];
        groupView.separatorColor = self.separatorColor;
        groupView.separatorSize = self.separatorSize;
        
        CGroupBackgroundInfo *groupBgInfo = nil;
        if ([self.delegate respondsToSelector:@selector(groupTableView:groupBackgroundInfoForGroupIndex:)])
        {
            groupBgInfo = [self.delegate groupTableView:self groupBackgroundInfoForGroupIndex:group];
            if (groupBgInfo != nil)
            {
                [groupView setGroupBackgroundImageWithImage:groupBgInfo.image borderEdgeInsets:groupBgInfo.borderEdgeInsets cornerRadius:groupBgInfo.cornerRadius];
            }
        }
        else
        {
            [groupView setGroupBackgroundImageWithImage:self.groupBgImage borderEdgeInsets:self.groupBgEdgeInsets cornerRadius:self.cornerRadius];
        }
        
        [groupView setGroupWithCells:cells];
        groupView.backgroundColor = self.groupBackgroundColor;
        [self.scrollView addSubview:groupView];
        
        curContentH += groupView.height;
        [self.groups addObject:groupView];
        [groupView release];
        
        //add header view
        if ([self.delegate respondsToSelector:@selector(groupTableView:viewForFooterInGroup:)])
        {
            UIView *footerView = [self.delegate groupTableView:self viewForFooterInGroup:group];
            if (footerView != nil)
            {
                footerView.frame = CGRectMake(self.borderEdgeInsets.left, curContentH+self.groupSpacing/2, self.width-2*self.borderEdgeInsets.left, footerView.height);
                curContentH += footerView.height;
                [self.scrollView addSubview:footerView];
                [self.dicFooterView setObject:footerView forKey:[NSNumber numberWithInteger:group]];
            }
        }
        
        curContentH += group==groupNumber-1 ? self.borderEdgeInsets.bottom : self.groupSpacing;
    }
    self.scrollView.contentSize = CGSizeMake(self.width, curContentH);
}

#pragma mark gesture recognizer

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];
    CGPoint tapPoint = [touch locationInView:self];

    tapPoint.y += self.scrollView.contentOffset.y;
    self.curSelectedIndexPath = nil;
    for (NSInteger i=0; i<self.groups.count; i++)
    {
        CGroupTableViewGroup *groupView = [self.groups objectAtIndex:i];
        if (CGRectContainsPoint(groupView.frame, tapPoint))
        {
            tapPoint.x -= groupView.left;
            tapPoint.y -= groupView.top;
            for (NSInteger j=0; j<groupView.cells.count; j++)
            {
                CGroupTableViewCell *cellView = [groupView.cells objectAtIndex:j];
                if (CGRectContainsPoint(cellView.frame, tapPoint) && cellView.selectable == YES && cellView.userInteractionEnabled == YES)
                {
                    self.curSelectedIndexPath = [NSIndexPath indexPathForRow:j inSection:i];
                    [[self cellAtIndexPath:self.curSelectedIndexPath] setSelectedState:YES animated:NO];
                    break;
                }
            }
            break;
        }
    }
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    if (self.curSelectedIndexPath != nil)
    {
        [[self cellAtIndexPath:self.curSelectedIndexPath] setSelectedState:NO animated:NO];
        self.curSelectedIndexPath = nil;
    }
}

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
    if (self.curSelectedIndexPath != nil)
    {
        [[self cellAtIndexPath:self.curSelectedIndexPath] setSelectedState:NO animated:NO];
        self.curSelectedIndexPath = nil;
    }
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    if (self.curSelectedIndexPath != nil)
    {
//        self.preSelectedIndexPath = self.curSelectedIndexPath;
        if ([self.delegate respondsToSelector:@selector(groupTableView:didSelectRowAtIndexPath:)])
        {
            [self.delegate groupTableView:self didSelectRowAtIndexPath:self.curSelectedIndexPath];
        }
        [[self cellAtIndexPath:self.curSelectedIndexPath] setSelectedState:NO animated:YES];
    }
}

@end
